{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hai,my name is LIU YING\n",
      "Hai,my name is MICHI STANGLE\n"
     ]
    }
   ],
   "source": [
    "# 属性案例\n",
    "# 创建Student类，描述学生类\n",
    "# 学生具有Student.name属性\n",
    "# 但name格式并不统一\n",
    "# 可以用增加一个函数，然后自动调用的方式，但很蠢\n",
    "class Student():\n",
    "    def __init__(self,name,age):\n",
    "        self.name = name\n",
    "        self.age = age\n",
    "        \n",
    "        # 如果不想修改代码\n",
    "        self.setName(name)\n",
    "        \n",
    "        \n",
    "    # 介绍下自己\n",
    "    def intro(self):\n",
    "        print(\"Hai,my name is {0}\".format(self.name))\n",
    "    def setName(self,name):\n",
    "        self.name = name.upper()\n",
    "        \n",
    "s1 = Student(\"LIU Ying\",19.8)\n",
    "s2 = Student(\"michi stangle\",24.0)\n",
    "\n",
    "s1.intro()\n",
    "s2.intro()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# peroperty案例\n",
    "# 定义一个Person类，具有name，age属性\n",
    "# 对于任意输入的姓名，我们希望都用大学方式保存\n",
    "# 年龄，我们希望内部统一用整数保存\n",
    "# x = property（fget，fset，fdel，doc）\n",
    "\n",
    "class Person():\n",
    "    '''\n",
    "    这是一个人，一个高尚的人，一个脱离了低级趣味的人\n",
    "    他还有属性\n",
    "    '''\n",
    "    # 函数的名称可以任意\n",
    "    def fget(self):\n",
    "        return self._name * 2\n",
    "    \n",
    "    def fset(self,name):\n",
    "        # 所有输入的姓名以大写形式保存\n",
    "        self._name = name.upper()\n",
    "    \n",
    "    def fdel(self):\n",
    "        self._name = \"NoName\"\n",
    "        \n",
    "    name = property(fget,fset,fdel,\"对name进行下下操作\")\n",
    "    \n",
    "# 作业：\n",
    "# 1.在用户输入年龄的时候，可以输入整数，小数，浮点数\n",
    "# 2.但内部为了数据清洁，我们同一需要保存整数，直接舍去小数点"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "TULINGTULING\n"
     ]
    }
   ],
   "source": [
    "p1 = Person()\n",
    "p1.name = \"TuLing\"\n",
    "print(p1.name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'__module__': '__main__', '__doc__': '\\n    这是一个人，一个高尚的人，一个脱离了低级趣味的人\\n    他还有属性\\n    ', 'fget': <function Person.fget at 0x7f2f0c0fe268>, 'fset': <function Person.fset at 0x7f2f0c0fe400>, 'fdel': <function Person.fdel at 0x7f2f0c0fe510>, 'name': <property object at 0x7f2f0c10d188>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>}\n",
      "\n",
      "    这是一个人，一个高尚的人，一个脱离了低级趣味的人\n",
      "    他还有属性\n",
      "    \n",
      "Person\n",
      "(<class 'object'>,)\n"
     ]
    }
   ],
   "source": [
    "# 类的内置属性举例\n",
    "print(Person.__dict__)\n",
    "print(Person.__doc__)\n",
    "print(Person.__name__)\n",
    "print(Person.__bases__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "哈哈，我被调用了\n"
     ]
    }
   ],
   "source": [
    "# init 举例\n",
    "class A():\n",
    "    def __init__(self,name = 0):\n",
    "        print(\"哈哈，我被调用了\")\n",
    "        \n",
    "a = A()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "哈哈，我被调用了\n",
      "我被调用了again\n"
     ]
    }
   ],
   "source": [
    "# __call__ 举例\n",
    "class A():\n",
    "    def __init__(self,name = 0):\n",
    "        print(\"哈哈，我被调用了\")\n",
    "    \n",
    "    def __call__(self):\n",
    "        print(\"我被调用了again\")\n",
    "a = A()\n",
    "a()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "哈哈，我被调用了\n",
      "图灵学院的例子\n"
     ]
    }
   ],
   "source": [
    "# __call__ 举例\n",
    "class A():\n",
    "    def __init__(self,name = 0):\n",
    "        print(\"哈哈，我被调用了\")\n",
    "    \n",
    "    def __call__(self):\n",
    "        print(\"我被调用了again\")\n",
    "\n",
    "    def __str__(self):\n",
    "        return \"图灵学院的例子\"\n",
    "a = A()\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NoName\n",
      "没找到呀没找到\n",
      "addr\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "# __getattr__\n",
    "\n",
    "# __call__ 举例\n",
    "class A():\n",
    "    name = \"NoName\"\n",
    "    age = 18\n",
    "    \n",
    "    def __getattr__(self,name):\n",
    "        print(\"没找到呀没找到\")\n",
    "        print(name)\n",
    "    \n",
    "a = A()\n",
    "print(a.name)\n",
    "print(a.addr)\n",
    "# 作业：\n",
    "# 为什么会打印第四句话，而且第四句话打印的是None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{}\n",
      "设置属性:age\n"
     ]
    }
   ],
   "source": [
    "# __setattr__ 案例\n",
    "class Person():\n",
    "    def __init__(self):\n",
    "        pass\n",
    "    \n",
    "    def __setattr__(self,name,value):\n",
    "        print(\"设置属性:{0}\".format(name))\n",
    "        # 下面语句会导致问题，死循环\n",
    "        # self.name = value\n",
    "        # 此种情况，为了避免死循环，规定统一调用父类魔法函数\n",
    "        super().__setattr__(name,value)\n",
    "        \n",
    "p = Person()\n",
    "print(p.__dict__)\n",
    "p.age = 18"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "哈哈,<__main__.Student object at 0x7f2f0c11e668>会比<__main__.Student object at 0x7f2f0c11e630>大吗？\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "# __gt__ 案例\n",
    "\n",
    "class Student():\n",
    "    def __init__(self,name):\n",
    "        self._name = name\n",
    "            \n",
    "    def __gt__(self,obj):\n",
    "        print(\"哈哈,{0}会比{1}大吗？\".format(self,obj))\n",
    "        return self._name > obj._name\n",
    "    \n",
    "# 作业：\n",
    "# 字符串的比较是按什么规则\n",
    "stu1 = Student(\"one\")\n",
    "stu2 = Student(\"two\")\n",
    "\n",
    "print(stu1 > stu2)\n",
    "\n",
    "# 作业：\n",
    "# 下面显示结果不太美观，能否改成形如“哈哈，one 会比 two 大吗”"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<__main__.Person object at 0x7f2f0c0bb128>\n",
      "Eating......\n",
      "<class '__main__.Person'>\n",
      "Playing......\n",
      "<class '__main__.Person'>\n",
      "Playing......\n",
      "Saying......\n",
      "Saying......\n"
     ]
    }
   ],
   "source": [
    "# 三种方法的案例\n",
    "class Person:\n",
    "    # 实例方法\n",
    "    def eat(self):\n",
    "        print(self)\n",
    "        print(\"Eating......\")\n",
    "    # 类方法\n",
    "    # 类方法的第一个参数，一般命名为cls，区别于self\n",
    "    @classmethod\n",
    "    def play(cls):\n",
    "        print(cls)\n",
    "        print(\"Playing......\")\n",
    "    # 静态方法\n",
    "    # 不需要用第一个参数表示自身或者类\n",
    "    @staticmethod\n",
    "    def say():\n",
    "        print(\"Saying......\")\n",
    "        \n",
    "yueyue = Person()\n",
    "\n",
    "# 实例方法\n",
    "yueyue.eat()\n",
    "# 类方法\n",
    "Person.play()\n",
    "yueyue.play()\n",
    "# 静态方法\n",
    "Person.say()\n",
    "yueyue.say()\n",
    "\n",
    "# 作业：\n",
    "# 自行查找三种方法内存使用方面的区别"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
